<?php
// +----------------------------------------------------------------------
// | 有理想的地方，地狱都是天堂。
// +----------------------------------------------------------------------
// | Copyright @ df81.com 版权所有
// +----------------------------------------------------------------------
// | 作者: 南国老符 邮箱：1062129401@qq.com
// +----------------------------------------------------------------------

namespace app\api\model\v1;
use think\Model;
use app\api\controller\v1\Replace as apiReplaceController;
use think\facade\Db;

class Common extends Model{
    /**
     * 详情页，如：产品详情，新闻详情...
     * id 表的ID
     * table 数据表
     * userid 用户ID
     * lang 语言
    **/
    static function view($id = 0, $table = 'news', $userid = 0, $lang = 'cn'){
        // 转为小写字母
        $general = new \common\General();
        $table = $general->capital_to_underline($table);
        $host = request()->host(true);

        if(!empty($id)){
            $where[] = ["$table.id","=",$id];
        }else{
            $where[] = ["$table.urlroute","=",input('urlroute')];
            $where[] = ["$table.lang","=",$lang];
        }

        //视图查询
        $rs = Db::view($table,'*')
            ->view('user',['avatar,logo,username,nickname,company'],"$table.userid=user.id")
            ->where($where);

            // 地区分站
            $cityid = Db::name('area')->where('bind_domain',$host)->value('id');
            if(!empty($cityid)) $rs = $rs->whereRaw("$table.cityid = 0 or find_in_set($cityid,$table.cityid)");
            $rs = $rs->find();

            // 分类
            $sortList = Db::name('sort')->where('id','in',explode(',',$rs['sortid']))->field('id,title as sort_title,description as sort_description')->select();
            $sort_title = $sort_description = '';
            if(!empty($sortList)){
                foreach ($sortList as $key => $v) {
                    $sort_title = $v['sort_title'].'，'; $sort_description = $v['sort_description'].'，';
                }
                $sort_title = trim($sort_title,'，'); $sort_description = trim($sort_description,'，');
            }
            $rs['sort_title'] = $sort_title;
            $rs['sort_description'] = $sort_description;
        
        // 站内链接处理
        $moduleWhere[] = ['tabledir','=',$table]; $moduleWhere[] = ['lang','=',$lang];
        $isdisplay = Db::name('module')->where($moduleWhere)->value('isdisplay');
        if(!empty($rs['content1']) and in_array('keyword',explode(',',$isdisplay))){
            $apiReplaceController = new apiReplaceController;
            $apiReplaceController ->content($rs['content1'],$table,$lang);
            $rs['content1'] = $apiReplaceController;
        }
        
        // 城市分站TDK
        $cityRs = Common::area_view($host);
        if(!empty($cityRs)){
            $keyword = $rs['keyword']; $description = $rs['description'];
            $keywordArray = explode('，',$keyword);
            if(count($keywordArray) == 1){
                $keyword = $cityRs['abbreviation'].$keyword;
                $description = str_replace($keyword,$cityRs['abbreviation'].$keyword,$description);
            }else{
                $keyword = '';
                foreach ($keywordArray as $str){
                    $keyword .= $cityRs['abbreviation'].$str.'，';
                    $description = str_replace($str,$cityRs['abbreviation'].$str,$description);
                }
                $keyword = rtrim($keyword,'，');
            }
            if(empty($rs['city_keyword'])){
                $rs['keyword'] = $keyword;
            }else{
                $rs['keyword'] = str_replace('[city]',$cityRs['abbreviation'],$rs['city_keyword']);
            }
            if(empty($rs['city_description'])){
                $rs['description'] = $description;
            }else{
                $rs['description'] = str_replace('[city]',$cityRs['abbreviation'],$rs['city_description']);
            }
            $rs['content1'] = str_replace('[city]',$cityRs['abbreviation'],$rs['content1']);
        }
        
        // 格式化日期
        $rs['Ymd'] = date('Y-m-d',$rs['update_time']); $rs['YmdHi'] = date('Y-m-d H:i',$rs['update_time']);
       
        return $rs;
    }

    /**
     * 列表页，如：产品列表、新闻列表、关于我们列表等
     * table 表
     * sortid 分类ID
     * field 查询字段，*表示所有字段
     * lang 语言
     * num 每页显示数量
     * order 排序
     * signid 状态值
     * keyword 查询关键词
     * userid 信息表的userid
     * id 包含id的数组，如：1,2,3等
     * notid 不包含的id数组，如1,2,3等
    */
    static function index($table = 'product', $sortid = 0, $field = '*', $lang = '', $num = 12, $order = '', $signid = '', $keyword = '', $userid = '', $id = '', $notid = ''){
        // 转为小写字母
        $general = new \common\General();
        $table = $general->capital_to_underline($table);

        $where[] = ["$table.lang",'=',$lang];
        $where[] = ["$table.signid",'=',1];

        //父类找子类，查询类别下包含的信息
        $sortidArr = ""; $sortWhere[] = ['lang','=',$lang]; $sortWhere[] = ['tabledir','=',$table];
        // $sortArr = getChildSort(Db::name('sort')->where($sortWhere)->select(),$sortid);
        // $countSort = count($sortArr)-1;
        // foreach($sortArr as $k => $w){
        //     if($k != $countSort){
        //         $sortidArr .= $w['id'].",";
        //     }else{
        //         $sortidArr .= $w['id'];
        //     }
        // }
        // if(!empty($sortid)) $sortidArr = $sortid.','.$sortidArr;
        // $sortidArr = rtrim($sortidArr,',');
        
        // 单页表
        if($table == 'about' and empty($keyword)) $where[] = ["$table.parentid",'=',0];
        
        //列表页地址
        if(!empty($sortid)){
            $path = get_category_url($sortid,$table);
        }else{
            $path = get_list_url($table);
        }
        $path = str_replace('.html','',$path)."[PAGE]\/";
        $pageParam = array();
        if(!empty($keyword)) $pageParam = array('keyword'=>$keyword);
        // 包含某组id
        if(!empty($id)){
            $where[] = ["$table.id",'in',$id];
            if(empty($pageParam)){
                $pageParam = array('id'=>$id);
            }else{
                $pageParam += array('id'=>$id);
            }
        }
        // 不包含某组id
        if(!empty($notid)){
            $where[] = ["$table.id",'not in',$notid];
            if(empty($pageParam)){
                $pageParam = array('notid'=>$notid);
            }else{
                $pageParam += array('notid'=>$notid);
            }
        }
        // 本店商品
        if(!empty($userid)){
            $where[] = ["$table.userid",'=',$userid];
            $pageParam += array('userid'=>$userid);
        }

        if(request()->isMobile()){
            $clientWhere = 'find_in_set(\'wap\',client)';
        }else{
            $clientWhere = 'find_in_set(\'pc\',client)';
        }
        
        //视图查询
        $rs = Db::view($table,$field)
            ->view('user',['avatar,logo,username,nickname,company'],"$table.userid=user.id")
            ->where($where)->where($clientWhere);
            if(!empty($sortid)){
                $rs = $rs->whereRaw("$table.sortid = 0 or find_in_set($sortid,$table.sortid)");
            }
            $rs = $rs->where("$table.title|$table.seotitle|$table.keyword|$table.description|$table.content1",'like',"%$keyword%");

            // 地区分站
            $cityid = Db::name('area')->where('bind_domain',request()->host(true))->value('id');
            if(!empty($cityid)) $rs = $rs->whereRaw("$table.cityid = 0 or find_in_set($cityid,$table.cityid)");
            $rs = $rs->order($order)->paginate([
                'path'=> $path,
                'list_rows'=> $num,
                'query'=> $pageParam,
            ]);

            // 分类
            $sortList = Db::name('sort')->where($sortWhere)->field('id,title as sort_title,description as sort_description')->select();
            $tableSort = array('table'=>$table,'sort'=>$sortList);
            $rs = $rs->each(function($item, $key) use ($tableSort){
                    $item['url'] = get_view_url($item['id'], $tableSort['table']);
                    // 格式化日期
                    $item['Ymd'] = date('Y-m-d',$item['update_time']);
                    $item['YmdHi'] = date('Y-m-d H:i',$item['update_time']);
                    $item['sort_title'] = $item['sort_description'] = null;

                    // 分类
                    $sort_title = $sort_description = '';
                    foreach ($tableSort['sort'] as $key => $v) {
                        if(in_array($v['id'],explode(',',$item['sortid']))){
                            $sort_title = $v['sort_title'];
                            $sort_description = $v['sort_description'];
                        }
                    }
                    $item['sort_title'] = $sort_title; $item['sort_description'] = $sort_description;

                    return $item;
                });
            
        return $rs;
    }
    
    /**
     * 分类
     * num 显示数量
     * lang 语言
     * tabledir 数据表
     * parentid 父类id
     * id 指定的ID，如：1,2,3
     * notid 排除的ID，如：1,2,3
     * signid 状态
     * field 检索字段
     * order 排序
    */
    static function sort_list($num = 5, $lang = 'cn', $tabledir = 'product', $parentid = 0, $id ='', $notid = '', $signid = 1, $field = 'id,title,short_title,seotitle,keyword,description,thumb,urlroute,config', $order = 'sequence desc'){
        if(!empty($id)) $where[] = ['id','in',$id];
        if(!empty($notid)) $where[] = ['id','not in',$notid];
        $where[] = ['lang','=',$lang]; $where[] = ['signid','=',$signid];
        $where[] = ['tabledir','=',$tabledir]; $where[] = ['parentid','=',$parentid];
        $rs = Db::name('sort')->where($where);
        
        /*城市分站*/
        $cityid = Db::name('area')->where('bind_domain',request()->host(true))->value('id');
        if(!empty($cityid)) $rs = $rs->whereRaw("cityid = 0 or find_in_set($cityid,cityid)");
        
        if(empty($field)) $field = 'title,short_title,seotitle,keyword,description,thumb,urlroute,config';
        if(empty($order)) $field = 'sequence desc';
        $rs = $rs->field($field)->order($order)->limit($num)->select();

        return $rs;
    }
    
    /**
     * 地区城市
     * bind_domain 绑定的域名
     * id 表的ID
     * urlroute 表的urlroute
     * lang 语言
     * parentid 父类id
     * is_domain 是否启用次级域名
     * signid 状态值
     * field 检索字段
    */
    static function area_view($bind_doamin = '', $id = 0, $urlroute = '', $lang = 'cn', $parentid = 0, $is_domain = 1, $signid = 1, $field = 'title,seotitle,keyword,description,content1,abbreviation,initial,thumb'){
        $where[] = ['lang','=',$lang];
        if(!empty($bind_doamin)) $where[] = ['bind_domain','=',$bind_doamin];
        if(!empty($id)) $where[] = ['id','=',$id];
        if(!empty($urlroute)) $where[] = ['urlroute','=',$urlroute];
        // if($parentid != '') $where[] = ['parentid','=',$parentid];
        // if($is_domain != '') $where[] = ['is_domain','=',$is_domain];
        // if($signid != '') $where[] = ['signid','=',$signid];
        
        $rs = Db::name('area')->where($where)->field($field)->find();
        
        return $rs;
    }
    
    /**
     * 广告友链
     * num 显示数量
     * lang 语言
     * att_type 属性，link友情链接，banner幻灯片
     * position 位置
     * field 检索字段
     * order 排序
    */
    static function ad($num = 5, $lang = 'cn', $att_type = 'banner', $position = 'index', $signid = 1, $field = 'id,title,description,thumb,linkurl', $order = 'sequence desc'){

        $where[] = ['lang','=',$lang]; $where[] = ['signid','=',$signid]; $where[] = ['att_type','=',$att_type]; $where[] = ['position','=',$position];
        $ad = Db::name('ad')->where($where);
        if(request()->isMobile()){
            $ad = $ad->where("find_in_set('wap',client)");
        }else{
            $ad = $ad->where("find_in_set('pc',client)");
        }
        /*城市分站*/
        $cityid = Db::name('area')->where('bind_domain',request()->host(true))->value('id');
        if(!empty($cityid)) $ad = $ad->whereRaw("cityid = 0 or find_in_set($cityid,cityid)");
        
        if(empty($field)) $field = 'title,description,thumb,linkurl';
        if(empty($order)) $field = 'sequence desc';
        $rs = $ad->field($field)->order($order)->limit($num)->select();

        return $rs;
    }
    
    /**
     * 在线客服
     * num 显示数量
     * lang 语言
     * att_type 属性
     * signid 状态
     * field 检索字段
     * order 排序
    */
    static function chat($num = 5, $lang = 'cn', $att_type = 'qq', $signid = 1, $field = 'id,att_type,account,title,thumb', $order = 'sequence desc'){
        $where[] = ['lang','=',$lang]; $where[] = ['signid','=',$signid]; $where[] = ['att_type','=',$att_type];
        $chat = Db::name('chat')->where($where);
        
        /*城市分站*/
        $cityid = Db::name('area')->where('bind_domain',request()->host(true))->value('id');
        if(!empty($cityid)) $chat = $chat->whereRaw("cityid = 0 or find_in_set($cityid,cityid)");
        
        if(empty($field)) $field = 'att_type,account,title,thumb';
        if(empty($order)) $field = 'sequence desc';
        $rs = $chat->field($field)->order($order)->limit($num)->select();

        return $rs;
    }
    
    /**
     * 自定义变量
     * lang 语言
     * field 检索字段
    */
    static function field($lang = 'cn', $field = 'id,fieldlabel,fieldvalue'){
        $where[] = ['lang','=',$lang];
        $rs = Db::name('field')->where($where);
        /*城市分站*/
        $cityid = Db::name('area')->where('bind_domain',request()->host(true))->value('id');
        if(!empty($cityid)) $rs = $rs->whereRaw("cityid = 0 or find_in_set($cityid,cityid)");
        $rs = $rs->field($field)->select();

        return $rs;
    }
    
    /**
     * 站点信息
     * lang 语言
     * cityDomain 城市分站域名
    */
    static function siteRs($lang = 'cn', $cityDomain = ''){
        $rs = Db::name('site')->where('lang',$lang)->find();
        
        /*城市分站 开始*/
        $cityWhere[] = ['bind_domain','=',$cityDomain]; $cityWhere[] = ['signid','=',1];
        $cityWhere[] = ['is_domain','=',1]; $cityWhere[] = ['lang','=',$lang];
        $cityRs = Db::name('area')->where($cityWhere)->whereNotNull('urlroute')->field('title,seotitle,keyword,description,content1,abbreviation,initial,thumb')->find();
        $rs['content1'] = $rs['abbreviation'] = $rs['initial'] = $rs['thumb'] = null;
        if(!empty($cityRs)){
            if(!empty($cityRs['seotitle'])){
                $rs['title'] = $cityRs['seotitle'];
            }else{
                if(!empty($rs['city_title'])){
                    $rs['title'] = str_replace('[city]',$cityRs['abbreviation'],$rs['city_title']);
                }
            }
            if(!empty($cityRs['keyword'])){
                $rs['keyword'] = $cityRs['keyword'];
            }else{
                if(!empty($rs['city_keyword'])){
                    $rs['keyword'] = str_replace('[city]',$cityRs['abbreviation'],$rs['city_keyword']);
                }
            }
            if(!empty($cityRs['description'])){
                $rs['description'] = $cityRs['description'];
            }else{
                if(!empty($rs['city_description'])){
                    $rs['description'] = str_replace('[city]',$cityRs['abbreviation'],$rs['city_description']);
                }
            }
            $rs['content1'] = $cityRs['content1'];
            $rs['abbreviation'] = $cityRs['abbreviation'];
            $rs['initial'] = $cityRs['initial'];
            $rs['thumb'] = $cityRs['thumb'];
        }
        /*城市分站 结束*/
        
        return $rs;
    }
    
    /**面包屑导航：子类找父类，如：关于我们导航、产品导航等
    * table 表
    * tabledir 模块目录
    * lang 语言
    * id 页面ID或分类ID
    */
    static function crumb($table = 'sort', $tabledir = 'product', $id, $lang = ''){
        // 转为小写字母
        $general = new \common\General();
        $table = $general->capital_to_underline($table);
        $tabledir = $general->capital_to_underline($tabledir);

        if($table == 'sort') $where[] = ['tabledir','=',$tabledir];//如果是分类表sort
        $where[] = ['lang','=',$lang];
        // 追加链接
        $data = Db::name($table)->where($where)->order('sequence desc,id desc')->select()
            ->each(function($item, $key) use ($tabledir){
                    $item['url'] = get_category_url($item['id'], $tabledir);
                    return $item;
                });
        $rs = getParentSort($data,$id);
        
        return $rs;
    }

    /**关键词tag列表
    * table 表
    * field 查询字段，*表示所有字段
    * lang 语言
    * num 每页显示数量
    * order 排序
    * keyword 查询关键词
    */
    static function tagList($table = 'news', $field = '*', $lang = 'cn', $urlroute = '', $keyword = '', $num = 10, $order = 'id desc'){
        // 转为小写字母
        $general = new \common\General();
        $table = $general->capital_to_underline($table);

        $where[] = ["$table.lang",'=',$lang];
        $where[] = ["$table.signid",'<',9];

        //列表页地址
        $lang_pre = '';
        if(empty(config('global.url.bind_lang'))){
            $lang_pre = '/'.$lang;
        }
        $path = $lang_pre.'/tags/'.$urlroute.'/'."[PAGE]".'\/';

        //视图查询
        $rs = Db::view($table,$field)
            ->view('sort',['title'=>'sort_title','seotitle'=>'sort_seotitle','keyword'=>'sort_keyword','description'=>'sort_description'],"$table.sortid=sort.id");
            // 地区分站
            $domain = request()->host(true);
            if(!empty($domain) and !in_array($domain,array('127.0.0.1','localhost'))){
                $cityid = Db::name('area')->where('bind_domain',$domain)->value('id');
                if(!empty($cityid)) $rs = $rs->whereRaw("$table.cityid = 0 or find_in_set($cityid,$table.cityid)");
            }
            $rs = $rs->where($where)->where("$table.title|$table.seotitle|$table.keyword|$table.description|$table.content1",'like',"%$keyword%")->order($order)
            ->paginate([
                'path'=> $path,
                'list_rows'=> $num,
            ])
            ->each(function($item, $key) use ($table){
                $item['url'] = get_view_url($item['id'], $table);
                return $item;
            });

        return $rs;
    }

    /**标签云
    @ table 表
    @ field 查询字段，*表示所有字段
    @ lang 语言
    @ limit 数量
    */
    static function tagCloud($table = 'news', $field = '*', $lang = 'cn', $limit = 100){
        // 转为小写字母
        $general = new \common\General();
        $table = $general->capital_to_underline($table);

        $where[] = ["lang",'=',$lang];
        $where[] = ["signid",'<',9];

        //关键词表
        if($limit == 0){//不限制
            $keywordList = Db::name('keyword')->where('lang','=',$lang)->field($field)->select();
        }else{
            $keywordList = Db::name('keyword')->where('lang','=',$lang)->field($field)->limit($limit)->orderRand()->select();
        }
        
        foreach ($keywordList as $kwRs) {
            $rsKeyword = $kwRs['keyword'];
            $count = Db::name($table)->where($where)
                ->where("title|seotitle|keyword|description|content1",'like',"%$rsKeyword%");
                // 地区分站
                $domain = request()->host(true);
                if(!empty($domain) and !in_array($domain,array('127.0.0.1','localhost'))){
                    $cityid = Db::name('area')->where('bind_domain',$domain)->value('id');
                    if(!empty($cityid)) $count = $count->whereRaw("cityid = 0 or find_in_set($cityid,cityid)");
                }
                $count = $count->count();
            $rs[] = array($kwRs['urlroute'],$kwRs['keyword'],$count);
        }

        return $rs;
    }

    /**地区/标签地图
    @ table 表
    @ field 查询字段，*表示所有字段
    @ lang 语言
    @ letterArr 字母数组
    @ type 类型：tag标签，area地区
    */
    static function sitemap($table = 'news', $field = '*', $lang = 'cn', $letterArr, $type = 'tag'){
        // 转为小写字母
        $general = new \common\General();
        $table = $general->capital_to_underline($table);
        
        $where[] = ["lang",'=',$lang];
        $where[] = ["signid",'<',9];

        //类型
        switch ($type) {
            case 'area'://地区
                $cityWhere[] = ['lang','=',config('lang.default_lang')]; $cityWhere[] = ['is_domain','=',1]; $cityWhere[] = ['signid','=',1];
                $keywordList = Db::name('area')->where($cityWhere)->whereNotNull('bind_domain')->field($field)->select();
                break;
            default://标签
                $keywordList = Db::name('keyword')->where('lang','=',$lang)->field($field)->select();
                break;
        }
        
        //字母和数组拼接
        foreach ($letterArr as $letter) {
            $keyArr = array();
            foreach ($keywordList as $kwRs) {
                $first = substr($kwRs['urlroute'],0,1);
                if($first == $letter){//首字母和a-z相等
                    switch ($type) {
                        case 'area'://地区
                            $rsKeyword = $kwRs['title'];
                            $count = 0;
                            $bind_domain = request()->scheme().'://'.$kwRs['bind_domain'];
                            break;
                        default://标签
                            $rsKeyword = $kwRs['keyword'];
                            $count = Db::name($table)->where($where)->where("title|seotitle|keyword|description|content1",'like',"%$rsKeyword%");
                                // 地区分站
                                $domain = request()->host(true);
                                if(!empty($domain) and !in_array($domain,array('127.0.0.1','localhost'))){
                                    $cityid = Db::name('area')->where('bind_domain',$domain)->value('id');
                                    if(!empty($cityid)) $count = $count->whereRaw("cityid = 0 or find_in_set($cityid,cityid)");
                                }
                                $count = $count->count();
                                $bind_domain = null;
                            break;
                    }
                    $keyArr[] = array($kwRs['urlroute'],$rsKeyword,$count,$bind_domain);
                }
            }
            $rs[] = array($letter,$keyArr);
        }

        return $rs;
    }

	/*路径安全校验
    @path 用户提交过来的路径
    @返回：true安全，false风险
    */
    static function allowPath($path){
        //若发现path里面跟了../则是非法路径,重置path为/根目录
        //防止基础模式攻击 /admin.php/url?mulu=%2F..%2F..%2F..%2Fapplication%2Fadmin%2Fcontroller&amp;lang=cn
        if (strpos($path, './') !== false || strpos($path, '../') !== false) {
            return false;
        }
        //若发现path里面跟了../则是非法路径,重置path为/根目录
        //防止/dir.php?filename=.\./.\./etc/passwd模式转义攻击
        if (strpos($path, '..%2F') !== false || strpos($path, '\.') !== false) {
            return false;
        }
        return true;
    }
}